/**
 * @details: 命令行的入口
 * @brief: 
 * @version: 1.0
 * @author: liuri
 * @Date: 2021-10-05 03:28:07
 * @LastEditors: liuri
 * @LastEditTime: 2021-10-07 01:36:30
 * @FilePath: /TestProject/cPath/vtysh/vtysh.c
 * @Copyright (C) 2021 liuri. All rights reserved.
 */

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "vtysh.h"
#include "cmd_readline.h"
#include "vty.h"
#include "cmd.h"

struct vty *vty;



/**
 * @brief: 将输入的字符串切割成vector,分量是字符串
 * @param {*}
 * @return {*}
 */
vector cmd_make_strvec (const char *string)
{
    const char *cp, *start;
    char *token;
    int strlen;
    vector strvec;

    if (string == NULL)
        return NULL;

    cp = string;

    /* Skip white spaces. */
    while (isspace ((int) *cp) && *cp != '\0')
        cp++;

    /* Return if there is only white spaces */
    if (*cp == '\0')
        return NULL;

    if (*cp == '!' || *cp == '#')
        return NULL;

    /* Prepare return vector. */
    strvec = vector_init (VECTOR_MIN_SIZE);

    /* Copy each command piece and set into vector. */
    while (1) 
    {
        start = cp;
        while (!(isspace ((int) *cp) || *cp == '\r' || *cp == '\n') && *cp != '\0')
            cp++;
        strlen = cp - start;
        token = malloc (strlen + 1);
        memcpy (token, start, strlen);

        *(token + strlen) = '\0';

        vector_set (strvec, token);

        while ((isspace ((int) *cp) || *cp == '\n' || *cp == '\r') && *cp != '\0')
            cp++;

        if (*cp == '\0')
            return strvec;
    }
}


void
cmd_free_strvec (vector v)
{
    unsigned int i;
    char *cp;

    if (!v)
    return;

    for (i = 0; i < vector_max (v); i++)
    if ((cp = vector_slot (v, i)) != NULL)
        free (cp);

    vector_free (v);
}




static int
cmd_parse(struct cmd_element *cmd_element,
          vector vline,
          int *argc, const char **argv)
{
  enum matcher_rv rv = cmd_element_match(cmd_element,
                                         FILTER_RELAXED,
                                         vline, -1,
                                         NULL, NULL,
                                         argc, argv);
  switch (rv)
    {
    case MATCHER_COMPLETE:
      return CMD_SUCCESS;

    case MATCHER_NO_MATCH:
      return CMD_ERR_NO_MATCH;

    case MATCHER_AMBIGUOUS:
      return CMD_ERR_AMBIGUOUS;

    case MATCHER_EXCEED_ARGC_MAX:
      return CMD_ERR_EXEED_ARGC_MAX;

    default:
      return CMD_ERR_INCOMPLETE;
    }
}


int cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd) 
{
    int ret;
    uint32_t i;
    vector cmd_vector;

    
    // 复制当前节点下的所有命令
    cmd_vector = vector_copy (cmd_node_ele_vec_get (vty->node));

    
    
    // 过滤
    for (i = 0; i < vector_max (vline); i++)
    {       
    
        // 匹配过滤
        ret = cmd_vector_filter(&matcher, cmd_vector, vline, i);
        if (ret != CMD_SUCCESS)
        {
            return ret;
        }

        // 匹配未结束，清理匹配器
        
        // 删除未命中节点，
    }

    // 判断命中未完成


    // 判断命中已完成

        // 匹配个数检查

        // 参数检查

        // 执行匹配的函数 
        // return (*matched_element->func) (matched_element, vty, argc, argv);

    return 0;
}


static int
vtysh_execute_func (const char *line, int pager)
{
    int ret, cmd_stat;
    vector vline;
    struct cmd_element *cmd;

    /* 将输入的字符串切割成vector,分量是字符串 */
    vline = cmd_make_strvec (line);
    if (vline == NULL)
        return CMD_SUCCESS;

    // 执行命令
    ret = cmd_execute_command (vline, vty, &cmd);

    // 释放vline 向量
    cmd_free_strvec (vline);

    cmd_stat = ret;
    switch (ret)
    {
        case CMD_WARNING:          
            break;
        case CMD_ERR_AMBIGUOUS: // 命令行安装错误等
            fprintf (stdout,"%% Ambiguous command.\n");
            break;
        case CMD_ERR_NO_MATCH:
            fprintf (stdout,"%% Unknown command.\n");
            break;
        case CMD_ERR_INCOMPLETE:
            fprintf (stdout,"%% Command incomplete.\n");
            break;        
    }
    return cmd_stat;
}


int vtysh_execute (const char *line)
{
    cmd_debug("Input commond is %s \n", line);
    return vtysh_execute_func (line, 1);
}


void vtysh_init()
{
     // 命令行加载
    cmd_init(0);

    // 终端初始化
    vty = vty_new ();
}




#ifdef VTYSH_TEST
int main(int argc, char *argv[])
{
    char *line_read = NULL;
  
    vtysh_init();

    while ((line_read = vtysh_readline_gets ("test#")))
        vtysh_execute (line_read);

    return 0;
}

#endif
